#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
Copyright [2017] [taurus.ai]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''

import csv
import libjournal
import kungfu.longfist.longfist_utils as lfutil

format_str = '%Y%m%d-%H:%M:%S'
format_d_str = format_str.replace('%', '&')

def nanofstr(time_str, time_format=format_str):
    import datetime, time
    dt = datetime.datetime.strptime(time_str, time_format)
    return long(time.mktime(dt.timetuple()) * 1e9)

def strfnano(nano, time_format=format_str):
    import datetime
    return datetime.datetime.fromtimestamp(nano / 1e9).strftime(time_format)

def dump_csv(csv_file, folders, names, t_msg_type, start_nano, end_nano, visualized=False, to_print=False):
    reader = libjournal.createReader(folders, names, 'journal_dumper', start_nano)
    csv_file = open(csv_file, 'wb')
    csv_writer = csv.writer(csv_file, delimiter=',')
    frame = reader.next()
    name = reader.name()
    header_printed = False
    while frame != None and frame.nano() < end_nano:
        msg_type = frame.msg_type()
        if msg_type == t_msg_type:
            row = lfutil.get_contents(frame)
            row.append(('h_extra_nano', 'l', frame.extra_nano()))
            row.append(('h_nano', 'l', frame.nano()))
            if visualized:
                row.append(('h_nano_s', 's', strfnano(frame.nano())))
            row.append(('h_msg_type', 'i', msg_type))
            row.append(('h_request_id', 'i', frame.request_id()))
            row.append(('h_source', 'i', frame.source()))
            row.append(('h_is_last', 'i', frame.is_last()))
            row.append(('h_error_id', 'i', frame.error_id()))
            row.append(('j_name', 's', name))
            if not header_printed:
                headers = map(lambda x:'{}({})'.format(x[0], x[1]), row)
                csv_writer.writerow(headers)
                if to_print:
                    print ','.join(headers)
                header_printed = True
            contents = map(lambda x: str(x[2]), row)
            csv_writer.writerow(contents)
            if to_print:
                print ','.join(contents)
        frame = reader.next()
        name = reader.name()

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('-n', '--name', help='journal name', type=str, default='')
    parser.add_argument('-m', '--msg_type', help='msg type to dump', type=int, default=0)
    parser.add_argument('-o', '--output', help='output file name', type=str, default='')
    parser.add_argument('-v', '--visualize', help='visualize the time', action="count", default=0)
    parser.add_argument('-p', '--print_out', help='print to console while dumping', action="count", default=0)
    parser.add_argument('-s', '--start', help='start time ({})'.format(format_d_str), type=str, default='19000101-00:00:00')
    parser.add_argument('-e', '--end', help='end time ({})'.format(format_d_str), type=str, default='29990101-00:00:00')
    args = parser.parse_args()
    ready_to_dump = True
    if len(args.name) == 0:
        print 'name (-n) need to be specified'
        print 'available names: ', libjournal.get_available_journal_names()
        ready_to_dump = False
    if args.msg_type == 0:
        print 'msg_type (-m) need to be specified'
        ready_to_dump = False
    if len(args.output) == 0:
        print 'output (-o) need to be specified'
        ready_to_dump = False
        
    if ready_to_dump:
        print 'dumping: '
        print 'name', args.name
        print 'msg_type', args.msg_type
        print 'start', args.start
        print 'end', args.end
        dump_csv(args.output, [libjournal.get_journal_folder(args.name)], [args.name], args.msg_type, nanofstr(args.start), nanofstr(args.end), args.visualize > 0, args.print_out > 0)